// Bot.cpp : Implementation of CBot

#include "stdafx.h"
#include "Bot.h"

#include <mshtml.h>
#include <string>
#include <algorithm>
#include <memory>

using namespace std;


// CBot

HWND GetNativeWnd(IHTMLElement* e);

STDMETHODIMP CBot::InterfaceSupportsErrorInfo(REFIID riid)
{
    static const IID* const arr[] = 
    {
        &IID_IBot
    };

    for (int i=0; i < sizeof(arr) / sizeof(arr[0]); i++)
    {
        if (InlineIsEqualGUID(*arr[i],riid))
            return S_OK;
    }
    return S_FALSE;
}

STDMETHODIMP CBot::Fill(IHTMLElement* e, BSTR v, LONG p)
{
    HWND hwnd = GetNativeWnd(e);

    // get child window depends on level (p)
    for(int i=0; i<p; i++)
    {
        hwnd = FindWindowExW(hwnd, NULL, NULL, NULL);
    }

    wstring value(v);
    for_each(value.cbegin(), value.cend(), [hwnd](const wchar_t c){
        SendMessageW(hwnd, WM_CHAR, c, 0);
    });

    return S_OK;
}



HWND GetNativeWnd(IHTMLElement* e)
{
    HRESULT hr;

    CComQIPtr<IHTMLObjectElement> obj(e);
    if(!obj)
        AtlThrow(E_NOINTERFACE);

    CComDispatchDriver disp;
    hr = obj->get_object(&disp);
    if(FAILED(hr))
        AtlThrow(hr);

    CComQIPtr<IOleInPlaceActiveObject> pao(disp);
    if(!pao)
        AtlThrow(E_NOINTERFACE);

    HWND hwnd;
    hr = pao->GetWindow(&hwnd);
    if(FAILED(hr))
        AtlThrow(hr);

    return hwnd;
}